using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Awaiter;
using MetaPages.Classes;
using Nsb.Classes;
using Yoshi.Classes;
using jQueryApi;

namespace MetaTests.Classes
{
    [IgnoreNamespace]
    public class TestSuite
    {
        public const string AllTestsName = "Run all tests";
        public static readonly Dictionary<string, TestSuite> Suites = new Dictionary<string, TestSuite>();
        public static jQueryObject Teller;
        public readonly string Name;
        public readonly Dictionary<string, Test> Tests = new Dictionary<string, Test>();

        public TestSuite(string name)
        {
            Name = name;
            Suites[name.ToLowerCase()] = this;
        }

        public void Run(string test)
        {
            RunAw(null, test);
        }

        public void RunAw(Await awp, string test)
        {
            Test tt = Tests[test.ToLowerCase()];
            if (tt != null)
            {
                tt.Suite = this;
                tt.Reset().RunTest(awp);
            }
            else
            {
                Inform.Error("Could not find test {0}", test);
                if (awp != null)
                    awp.Done();
            }
        }

        public static void RunMasterSuite()
        {
            TestSuite suite = GetTestSuiteByPage(AllPages.MasterPage);
            suite.Run(AllTestsName);
        }

        public Dictionary TestList()
        {
            return DropMenu.Listify(
                Tests,
                delegate(object a, object b) { return String.Compare(((Test)a).Name, ((Test)b).Name, true); },
                delegate(Dictionary dd, object o) { dd[((Test)o).Name] = ((Test)o).Name; });
        }

        public void RunAllAw(Await awp)
        {
            RunAw(awp, AllTestsName);
        }

        public static TestSuite GetTestSuiteByPage(string pageName)
        {
            string[] parts = pageName.Split(".");
            pageName = parts[parts.Length - 1];
            string className = "MetaTests.Pages." + pageName + "Tests";
            string keyName = pageName.ToLowerCase();
            try
            {
                if (Type.IsClass(Type.GetType(className)))
                {
                    if (Suites.ContainsKey(keyName))
                        return Suites[keyName];
                    return (TestSuite)Script.Eval("new " + className + "()");
                }
            }
            catch
            {
            }
            Inform.Trace("Missing test suite for page {0}", className);
            return null;
        }

        public static jQueryObject Tell(string msg)
        {
            if (Teller != null)
                if (!String.IsNullOrEmpty(msg))
                    Teller.Html(msg).Show();
                else
                    Teller.Html("").Hide();
            return Teller;
        }
    }
}